
#ifndef _UTIL_SOCKET_H_
#define _UTIL_SOCKET_H_

#include "xtypes.h"
#include "xstring.h"

int_t StartupSocketLib();
int_t CleanupSocketLib();


class CSocketRunTimeDaemon
{
public:
	CSocketRunTimeDaemon();
	~CSocketRunTimeDaemon();
};

class SocketAddr_t
{
public:
	uint32_t ip;
	uint16_t port;
public:
	CxString GetIpAddrString();
	CxString GetEndPointAddrString();
	
public:
	SocketAddr_t();
	SocketAddr_t(uint32_t _ip, uint16_t _port);
	SocketAddr_t(CxString _ip, uint16_t _port);
	~SocketAddr_t();
};

enum e_select_operation
{
	ESO_READ = 1,
	ESO_WRITE = 2,
	ESO_EXCEPT = 4,
	ESO_ERROR = 0x80000000,
};




class CDummyStreamSocket
{
public:
	uint_t GetHandle();
	void Assign(uint_t _Handle);

	DWORD Select( DWORD dwFlag, DWORD dwTimeOut );

public:
	CDummyStreamSocket();
	~CDummyStreamSocket();

protected:
	void _Init();
	void _Alloc();
	void _Tidy();

protected:
	uint_t m_Handle;
};






class CConnSocket : public CDummyStreamSocket
{
public:
	SocketAddr_t GetLocalAddr();
	SocketAddr_t GetRemoteAddr();

	xResult Connect( const SocketAddr_t & _EndPointAddr );
	xResult Disconnect();

	void SetConnected();
	void SetDisconnect();
	bool_t IsConnected();

	xResult ShutDown( int_t  how );
	int_t Recv( wildptr_t _Buf, int_t _Len, int_t _Flags );
	int_t Send( const wildptr_t _Buf, int_t _Len, int_t _Flags );

	int_t Read( wildptr_t _Buf, int_t _Len );
	int_t Write( const wildptr_t _Buf, int_t _Len );

	friend class CSocketHelper;

public:
	static CConnSocket * Create();
	virtual void Release();
public:
	CConnSocket();
	virtual ~CConnSocket();

	bool_t m_IsConnected;
}; //CConnSocket


class CListenSocket : public CDummyStreamSocket
{
public:
	bool_t Listen(ushort_t _Port, int_t _BackLog=64 );
	CConnSocket * Accept();

public:
	static CListenSocket * Create();
	virtual void Release();

public:
	CListenSocket();
	virtual ~CListenSocket();
};






class CGramSocket
{
};



class CSocketHelper
{
public:
	static xResult SetNoBlock(  CConnSocket* _SocketPtr, ulong_t _argval );
	static xResult SetNoDelay( CConnSocket* _SocketPtr, int_t _optval);
	static bool_t IsNoDelay( CConnSocket* _SocketPtr );
};


#endif //_UTIL_SOCKET_H_

